﻿using Autofac;
using Autofac.Extras.DynamicProxy;
using Net8.Project.Data;
using Net8.Project.Data.UnitOfWorks;
using Net8.Project.IService;
using Net8.Project.Service;
using System.Reflection;

namespace Net8.Project.Extension
{
    /// <summary>
    /// Autofac模块注册类
    /// 实现服务层、仓储层的依赖注入注册（支持构造函数注入和属性注入），并集成AOP拦截器
    /// </summary>
    public class AutofacModuleRegister : Autofac.Module
    {
        /// <summary>
        /// 重写Load方法，进行依赖注入注册
        /// </summary>
        /// <param name="builder">Autofac容器构建器</param>
        protected override void Load(ContainerBuilder builder)
        {
            var basePath = AppContext.BaseDirectory;

            // 获取服务和仓储层的程序集路径
            var servicesDllFile = Path.Combine(basePath, "Net8.Project.Service.dll");
            var repositoryDllFile = Path.Combine(basePath, "Net8.Project.Data.dll");

            // AOP拦截器类型集合
            var aopTypes = new List<Type>() { typeof(AOPServiceInterceptor), typeof(AOPTranInterceptor) };
            //builder.RegisterType<AOPServiceInterceptor>().WithProperty("IsWriteLog", false); // 注册AOP拦截器
            //builder.RegisterType<AOPTranInterceptor>(); // 注册事务拦截器

            #region 构造函数注册 服务，仓储
            // 注册泛型仓储接口和实现
            builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerDependency();
            // 注册泛型服务接口和实现，启用AOP拦截
            builder.RegisterGeneric(typeof(BaseService<>)).As(typeof(IBaseService<>))
                //.EnableInterfaceInterceptors()
                //.InterceptedBy(aopTypes.ToArray())
                .InstancePerDependency();
            #endregion

            #region 程序集，属性注册
            // 获取 Service.dll 程序集服务，并注册启用AOP拦截和属性注入
            var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblysServices)
                .AsImplementedInterfaces()
                //.EnableInterfaceInterceptors()
                //.InterceptedBy(aopTypes.ToArray())
                .PropertiesAutowired()
                .InstancePerDependency();

            // 获取 Repository.dll 程序集服务，并注册启用属性注入
            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblysRepository)
                .AsImplementedInterfaces()
                .PropertiesAutowired()
                .InstancePerDependency();

            // 声明事务工作单元类生命周期为会话模式 Scope，并注册启用属性注入
            builder.RegisterType<UnitOfWorkManage>().As<IUnitOfWorkManage>()
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .PropertiesAutowired();
            #endregion
        }
    }
}
